package com.ton.utils;

import com.alibaba.fastjson.JSON;
import com.kypj.frame.common.log.Log;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;


/**
 * JWT工具箱
 */

import java.text.ParseException;
import java.util.Base64;

public class JWTUtil {
    private static final byte[] secret = "dlb1l5j1cddjdjdsjs10O0oOO0O01l11lsljdhfjhs".getBytes();

    public static <T> String generate(T object) {
        //先建立一个头部Header
        /**
         * JWSHeader参数：1.加密算法法则,2.类型，3.。。。。。。。
         * 一般只需要传入加密算法法则就可以。
         * 这里则采用HS256
         * JWSAlgorithm类里面有所有的加密算法法则，直接调用。
         */
        String token = null;
        try {
            JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);
            //建立一个载荷Payload
            Payload payload = new Payload(JSON.toJSONString(object));
            //将头部和载荷结合在一起
            JWSObject jwsObject = new JWSObject(jwsHeader, payload);
            //建立一个密匙
            JWSSigner jwsSigner = new MACSigner(secret);
            //签名
            jwsObject.sign(jwsSigner);
            //生成token
            token = jwsObject.serialize();
            token = Base64.getEncoder().encodeToString(token.getBytes("utf-8"));
        } catch (Exception e) {
            throw new RuntimeException("加密错误");
        }
        return token;
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     * @throws ParseException
     * @throws JOSEException
     */
    public static <T> T verify(String token, Class<T> clazz) {

        try {
            token = new String(Base64.getDecoder().decode(token), "utf-8");

            //解析token
            JWSObject jwsObject = JWSObject.parse(token);
            //获取到载荷
            Payload payload = jwsObject.getPayload();
            //建立一个解锁密匙
            JWSVerifier jwsVerifier = new MACVerifier(secret);
            //判断token
            if (jwsObject.verify(jwsVerifier)) {
                return JSON.parseObject(payload.toString(), clazz);
            }
        } catch (Exception e) {
            Log.error(e);
        }
        return null;
    }

}
